﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using PloobsEngine.Light;
using PloobsEngine.Utils;
using PloobsEngine.Cameras;

namespace PloobsEngine.SceneControl
{
    public class WorldSerializator : IWorldSerializator
    {

        public WorldSerializator(EngineStuff engine)
        {
            this.engine = engine;
        }

        #region IWorldSerializator Members

        EngineStuff engine;
        const String comment = "Generated By PloobsStudio";

        public void Serialize(string fileName, IWorld world)
        {
            XmlTextWriter textWriter = new XmlTextWriter(fileName, Encoding.UTF8);
            textWriter.Formatting = Formatting.Indented;
            textWriter.WriteStartDocument();
            textWriter.WriteComment(comment);

            ///World
            ///Camera
            ///Light
            ///Objets
            ///trigers - NAO FEITO AINDA
            ///physic world properties
            ///dummies

            //textWriter.WriteStartElement("World", Convert.ToString((int)PhysicObjectTypes.BOXOBJECT));
            textWriter.WriteStartElement("World", "WorldSerializator");
            textWriter.WriteAttributeString("Type", world.GetType().AssemblyQualifiedName);
            world.Serialize(textWriter);

            ///Camera
            textWriter.WriteStartElement("CameraManager", null);
            foreach (CameraDescription cam in world.CameraManager.GetCamerasDescription())
            {
                textWriter.WriteStartElement("Camera", null);
                textWriter.WriteAttributeString("Type", cam.cam.GetType().AssemblyQualifiedName);
                textWriter.WriteElementString("Name", cam.name);
                textWriter.WriteElementString("Id", Convert.ToString(cam.cam.getId()));
                cam.cam.Serialize(textWriter);
                textWriter.WriteEndElement();
            }
            textWriter.WriteEndElement();

            ///Light
            textWriter.WriteStartElement("LightManager", null);
            foreach (ILight light in world.Lights)
            {
                textWriter.WriteStartElement("Light", null);
                textWriter.WriteAttributeString("Type", light.GetType().AssemblyQualifiedName);
                textWriter.WriteElementString("Name", light.Name);
                light.Serialize(textWriter);
                textWriter.WriteEndElement();
            }
            textWriter.WriteEndElement();

            ///Objects
            textWriter.WriteStartElement("ObjectsManager", null);
            foreach (IObject obj in world.Objects)
            {
                textWriter.WriteStartElement("Object", null);
                textWriter.WriteAttributeString("Type", obj.GetType().AssemblyQualifiedName);
                textWriter.WriteElementString("Id", Convert.ToString(obj.getId()));
                textWriter.WriteElementString("Name", obj.Name);
                obj.Serialize(textWriter);
                textWriter.WriteEndElement();
            }
            textWriter.WriteEndElement();

            ///Dummies
            textWriter.WriteStartElement("Dummies", null);
            foreach (IObject dummy in world.GetDummyes())
            {
                textWriter.WriteStartElement("Dummy", null);
                textWriter.WriteAttributeString("Type", dummy.GetType().AssemblyQualifiedName);                
                textWriter.WriteElementString("Name", dummy.Name);
                dummy.Serialize(textWriter);
                textWriter.WriteEndElement();
            }
            textWriter.WriteEndElement();


            textWriter.WriteEndElement();
            textWriter.WriteEndDocument();
            textWriter.Close();
        }


        public IWorld DeSerialize(string fileName)
        {

            XmlDocument xDoc = new XmlDocument();            
            xDoc.Load(fileName);
            XmlElement worldNode = xDoc["World"];
            String worldType = SerializerHelper.DeserializeAttributeBaseType<string>("Type", worldNode);
            Type tt = Type.GetType(worldType);
            IWorld world = Activator.CreateInstance(tt) as IWorld;
            world.DeSerialize(worldNode, engine);

            XmlElement lightManager = worldNode["LightManager"];
            XmlNodeList lightList = lightManager.ChildNodes;
            foreach (XmlNode node in lightList)
            {
                String type = SerializerHelper.DeserializeAttributeBaseType<string>("Type", node);
                Type t = Type.GetType(type);
                ILight light = Activator.CreateInstance(t) as ILight;
                light.Name = SerializerHelper.DeserializeBaseType<string>("Name", node);
                light.DeSerialize(node, engine, world);
                world.AddLight(light);
            }

            XmlElement objectManager = worldNode["ObjectsManager"];
            XmlNodeList objectList = objectManager.ChildNodes;
            foreach (XmlNode node in objectList)
            {
                String type = SerializerHelper.DeserializeAttributeBaseType<string>("Type", node);
                Type t = Type.GetType(type);
                IObject obj = Activator.CreateInstance(t) as IObject;
                obj.DeSerialize(node, engine, world);
                obj.Name = SerializerHelper.DeserializeBaseType<string>("Name", node);
                world.AddObject(obj);
            }


            XmlElement Dummies = worldNode["Dummies"];
            XmlNodeList dummylist= Dummies.ChildNodes;
            foreach (XmlNode node in dummylist)
            {
                String type = SerializerHelper.DeserializeAttributeBaseType<string>("Type", node);
                Type t = Type.GetType(type);
                IDummy dummy = Activator.CreateInstance(t) as IDummy;
                dummy.Name = SerializerHelper.DeserializeBaseType<string>("Name", node);
                dummy.DeSerialize(node, engine, world);                
                world.AddDummy(dummy);
            }


            XmlElement cameraManager = worldNode["CameraManager"];
            XmlNodeList cameraList = cameraManager.ChildNodes;
            foreach (XmlNode node in cameraList)
            {
                string name = SerializerHelper.DeserializeBaseType<string>("Name", node);
                int id = SerializerHelper.DeserializeBaseType<int>("Id", node);
                String type = SerializerHelper.DeserializeAttributeBaseType<string>("Type", node);
                Type t = Type.GetType(type);
                ICamera cam = Activator.CreateInstance(t) as ICamera;
                cam.setId(id);
                cam.DeSerialize(node, engine, world);
                world.CameraManager.AddCamera(cam,name);
            }



            return world;

        }

        #endregion
    }
}
